package com.example.bidding_agency_charge_backend.service.impl;

import com.example.bidding_agency_charge_backend.common.ErrorCode;
import com.example.bidding_agency_charge_backend.exception.BusinessException;
import com.example.bidding_agency_charge_backend.model.BinAgen;
import com.example.bidding_agency_charge_backend.model.Result;
import com.example.bidding_agency_charge_backend.model.enums.ProcessEnum;
import com.example.bidding_agency_charge_backend.service.BidAgenService;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author 邓哈哈
 * 2024/1/11 18:45
 * Function:
 * Version 1.0
 */
@Service
public class BidAgenServiceImpl implements BidAgenService {
    @Override
    public Result doCalculate(BinAgen binAgen) {
        String process = binAgen.getProcess();
        double cost = binAgen.getCost();
        double discount = binAgen.getDiscount() * 0.01;

        if (ProcessEnum.getEnumByValue(process) == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        ProcessEnum enumByValue = ProcessEnum.getEnumByValue(process);

        Result calResult = new Result();
        switch (Objects.requireNonNull(enumByValue)) {
            case GOODS: {
                System.out.println("goods");
                calResult = getResultByGoods(cost, discount);
                break;
            }
            case SERVICE: {
                System.out.println("service");
                calResult = getResultByService(cost, discount);
                break;
            }
            case PROJECT: {
                System.out.println("project");
                calResult = getResultByProject(cost, discount);
                break;
            }
            default: {
                break;
            }
        }

        return calResult;
    }

    public Result getResultByGoods(double cost, double discount) {
        double result = 0;
        String resultStr = "";
        int height = 5;

        if (cost < 100) {
            result = cost * 0.015;
            resultStr = String.format("%f × 1.5%% = %f\n\n合计收费 = %f万元",
                    cost, result, result);
            height = 3;
        } else if (cost < 500) {
            double res1 = 100 * 0.015;
            double res2 = (cost - 100) * 0.011;
            result = res1 + res2;
            resultStr = String.format("100 × 1.5%% = %f万元\n(%f - 100) × 1.1%% = %f万元\n\n合计收费 = %f + %f = %f万元",
                    res1, cost, res2, res1, res2, result);
            height = 4;
        } else if (cost < 1000) {
            double res1 = 100 * 0.015;
            double res2 = (500 - 100) * 0.011;
            double res3 = (cost - 500) * 0.008;
            result = res1 + res2 + res3;
            resultStr = String.format("100 × 1.5%% = %f万元\n(500 - 100) × 1.1%% = %f万元\n(%f - 500) × 0.8%% = %f万元\n\n合计收费 = %f + %f + %f= %f万元",
                    res1, res2, cost, res3, res1, res2, res3, result);
            height = 5;
        } else if (cost < 5000) {
            double res1 = 100 * 0.015;
            double res2 = (500 - 100) * 0.011;
            double res3 = (1000 - 500) * 0.008;
            double res4 = (cost - 1000) * 0.005;
            result = res1 + res2 + res3 + res4;
            resultStr = String.format("100 × 1.5%% = %f万元\n(500 - 100) × 1.1%% = %f万元\n(1000 - 500) × 0.8%% = %f万元\n(%f - 1000) × 0.5%% = %f万元\n\n合计收费 = %f + %f + %f + %f = %f万元",
                    res1, res2, res3, cost, res4, res1, res2, res3, res4, result);
            height = 6;
        } else if (cost < 10000) {
            double res1 = 100 * 0.015;
            double res2 = (500 - 100) * 0.011;
            double res3 = (1000 - 500) * 0.008;
            double res4 = (5000 - 1000) * 0.005;
            double res5 = (cost - 5000) * 0.0025;
            result = res1 + res2 + res3 + res4 + res5;
            resultStr = String.format("100 × 1.5%% = %f万元\n(500 - 100) × 1.1%% = %f万元\n(1000 - 500) × 0.8%% = %f万元\n(5000 - 1000) × 0.5%% = %f万元\n(%f - 5000) × 0.25%% = %f万元\n\n合计收费 = %f + %f + %f + %f + %f = %f万元",
                    res1, res2, res3, res4, cost, res5, res1, res2, res3, res4, res5, result);
            height = 7;
        } else if (cost < 50000) {
            double res1 = 100 * 0.015;
            double res2 = (500 - 100) * 0.011;
            double res3 = (1000 - 500) * 0.008;
            double res4 = (5000 - 1000) * 0.005;
            double res5 = (10000 - 5000) * 0.0025;
            double res6 = (cost - 10000) * 0.0005;
            result = res1 + res2 + res3 + res4 + res5 + res6;
            resultStr = String.format("100 × 1.5%% = %f万元\n(500 - 100) × 1.1%% = %f万元\n(1000 - 500) × 0.8%% = %f万元\n(5000 - 1000) × 0.5%% = %f万元\n(10000 - 5000) × 0.25%% = %f万元\n(%f - 10000) × 0.05%% = %f万元\n\n合计收费 = %f + %f + %f + %f + %f + %f = %f万元",
                    res1, res2, res3, res4, res5, cost, res6, res1, res2, res3, res4, res5, res6, result);
            height = 8;
        } else if (cost < 100000) {
            double res1 = 100 * 0.015;
            double res2 = (500 - 100) * 0.011;
            double res3 = (1000 - 500) * 0.008;
            double res4 = (5000 - 1000) * 0.005;
            double res5 = (10000 - 5000) * 0.0025;
            double res6 = (50000 - 10000) * 0.0005;
            double res7 = (cost - 50000) * 0.00035;
            result = res1 + res2 + res3 + res4 + res5 + res6 + res7;
            resultStr = String.format("100 × 1.5%% = %f万元\n(500 - 100) × 1.1%% = %f万元\n(1000 - 500) × 0.8%% = %f万元\n(5000 - 1000) × 0.5%% = %f万元\n(10000 - 5000) × 0.25%% = %f万元\n(50000 - 10000) × 0.05%% = %f万元\n(%f - 50000) × 0.035%% = %f万元\n\n合计收费 = %f + %f + %f + %f + %f + %f + %f = %f万元",
                    res1, res2, res3, res4, res5, res6, cost, res7, res1, res2, res3, res4, res5, res6, res7, result);
            height = 9;
        } else if (cost < 500000) {
            double res1 = 100 * 0.015;
            double res2 = (500 - 100) * 0.011;
            double res3 = (1000 - 500) * 0.008;
            double res4 = (5000 - 1000) * 0.005;
            double res5 = (10000 - 5000) * 0.0025;
            double res6 = (50000 - 10000) * 0.0005;
            double res7 = (100000 - 50000) * 0.00035;
            double res8 = (cost - 100000) * 0.00008;
            result = res1 + res2 + res3 + res4 + res5 + res6 + res7 + res8;
            resultStr = String.format("100 × 1.5%% = %f万元\n(500 - 100) × 1.1%% = %f万元\n(1000 - 500) × 0.8%% = %f万元\n(5000 - 1000) × 0.5%% = %f万元\n(10000 - 5000) × 0.25%% = %f万元\n(50000 - 10000) × 0.05%% = %f万元\n(100000 - 50000) × 0.035%% = %f万元\n(%f - 100000) × 0.008%% = %f万元\n\n合计收费 = %f + %f + %f + %f + %f + %f + %f + %f = %f万元",
                    res1, res2, res3, res4, res5, res6, res7, cost, res8, res1, res2, res3, res4, res5, res6, res7, res8, result);
            height = 10;
        } else if (cost < 1000000) {
            double res1 = 100 * 0.015;
            double res2 = (500 - 100) * 0.011;
            double res3 = (1000 - 500) * 0.008;
            double res4 = (5000 - 1000) * 0.005;
            double res5 = (10000 - 5000) * 0.0025;
            double res6 = (50000 - 10000) * 0.0005;
            double res7 = (100000 - 50000) * 0.00035;
            double res8 = (500000 - 100000) * 0.00008;
            double res9 = (cost - 500000) * 0.00006;
            result = res1 + res2 + res3 + res4 + res5 + res6 + res7 + res8 + res9;
            resultStr = String.format("100 × 1.5%% = %f万元\n(500 - 100) × 1.1%% = %f万元\n(1000 - 500) × 0.8%% = %f万元\n(5000 - 1000) × 0.5%% = %f万元\n(10000 - 5000) × 0.25%% = %f万元\n(50000 - 10000) × 0.05%% = %f万元\n(100000 - 50000) × 0.035%% = %f万元\n(500000 - 100000) × 0.008%% = %f万元\n (%f - 500000) × 0.006%% = %f万元\n\n合计收费 = %f + %f + %f + %f + %f + %f + %f + %f + %f = %f万元",
                    res1, res2, res3, res4, res5, res6, res7, res8, cost, res9, res1, res2, res3, res4, res5, res6, res7, res8, res9, result);
            height = 11;
        } else {
            double res1 = 100 * 0.015;
            double res2 = (500 - 100) * 0.011;
            double res3 = (1000 - 500) * 0.008;
            double res4 = (5000 - 1000) * 0.005;
            double res5 = (10000 - 5000) * 0.0025;
            double res6 = (50000 - 10000) * 0.0005;
            double res7 = (100000 - 50000) * 0.00035;
            double res8 = (500000 - 100000) * 0.00008;
            double res9 = (1000000 - 500000) * 0.00006;
            double res10 = (cost - 1000000) * 0.00004;
            result = res1 + res2 + res3 + res4 + res5 + res6 + res7 + res8 + res9 + res10;
            resultStr = String.format("100 × 1.5%% = %f万元\n(500 - 100) × 1.1%% = %f万元\n(1000 - 500) × 0.8%% = %f万元\n(5000 - 1000) × 0.5%% = %f万元\n(10000 - 5000) × 0.25%% = %f万元\n(50000 - 10000) × 0.05%% = %f万元\n(100000 - 50000) × 0.035%% = %f万元\n(500000 - 100000) × 0.008%% = %f万元\n(1000000 - 500000) × 0.006%% = %f万元\n(%f - 1000000) × 0.004%% = %f万元\n\n合计收费 = %f + %f + %f + %f + %f + %f + %f + %f + %f + %f = %f万元",
                    res1, res2, res3, res4, res5, res6, res7, res8, res9, cost, res10, res1, res2, res3, res4, res5, res6, res7, res8, res9, res10, result);
            height = 12;
        }

        return getResultCommon(result, discount, resultStr, height);
    }

    public Result getResultByService(double cost, double discount) {
        double result = 0;
        String resultStr = "";
        int height = 5;

        if (cost < 100) {
            result = cost * 0.015;
            resultStr = String.format("%f * 0.015 = %f", cost, result);
        } else if (cost < 500) {
            result = 100 * 0.015 + (cost - 100) * 0.008;
            resultStr = String.format("100 * 0.015 + (%f - 100) * 0.008 = %f", cost, result);
        } else if (cost < 1000) {
            result = 100 * 0.015 + (500 - 100) * 0.008 + (cost - 500) * 0.0045;
            resultStr = String.format("100 * 0.015 + (500 - 100) * 0.008 + (%f - 500) * 0.0045 = %f", cost, result);
        } else if (cost < 5000) {
            result = 100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (cost - 1000) * 0.0025;
            resultStr = String.format("100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (%f - 1000) * 0.0025 = %f", cost, result);
        } else if (cost < 10000) {
            result = 100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025
                    + (cost - 5000) * 0.001;
            resultStr = String.format("100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025" +
                    " + (%f - 5000) * 0.001 = %f", cost, result);
        } else if (cost < 50000) {
            result = 100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025
                    + (10000 - 5000) * 0.001 + (cost - 10000) * 0.0005;
            resultStr = String.format("100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025" +
                    " + (10000 - 5000) * 0.001 + (%f - 10000) * 0.0005 = %f", cost, result);
        } else if (cost < 100000) {
            result = 100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025
                    + (10000 - 5000) * 0.001 + (50000 - 10000) * 0.0005 + (cost - 50000) * 0.00035;
            resultStr = String.format("100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025" +
                    " + (10000 - 5000) * 0.001 + (50000 - 10000) * 0.0005 + (%f - 50000) * 0.00035 = %f", cost, result);
        } else if (cost < 500000) {
            result = 100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025
                    + (10000 - 5000) * 0.001 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035
                    + (cost - 100000) * 0.00008;
            resultStr = String.format("100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025" +
                    " + (10000 - 5000) * 0.001 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035" +
                    " + (%f - 100000) * 0.00008 = %f", cost, result);
        } else if (cost < 1000000) {
            result = 100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025
                    + (10000 - 5000) * 0.001 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035
                    + (500000 - 100000) * 0.00008 + (cost - 500000) * 0.00006;
            resultStr = String.format("100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025" +
                    " + (10000 - 5000) * 0.001 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035" +
                    " + (500000 - 100000) * 0.00008 + (%f - 500000) * 0.00006 = %f", cost, result);
        } else {
            result = 100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025
                    + (10000 - 5000) * 0.001 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035
                    + (500000 - 100000) * 0.00008 + (1000000 - 500000) * 0.00006 + (cost - 1000000) * 0.00004;
            resultStr = String.format("100 * 0.015 + (500 - 100) * 0.008 + (1000 - 500) * 0.0045 + (5000 - 1000) * 0.0025" +
                    " + (10000 - 5000) * 0.001 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035" +
                    " + (500000 - 100000) * 0.00008 + (1000000 - 500000) * 0.00006 + (%f - 1000000) * 0.00004 = %f", cost, result);
        }

        return getResultCommon(result, discount, resultStr, height);
    }

    public Result getResultByProject(double cost, double discount) {
        double result = 0;
        String resultStr = "";
        int height = 5;

        if (cost < 100) {
            result = cost * 0.01;
            resultStr = String.format("%f * 0.01 = %f", cost, result);
        } else if (cost < 500) {
            result = 100 * 0.01 + (cost - 100) * 0.007;
            resultStr = String.format("100 * 0.01 + (%f - 100) * 0.007 = %f", cost, result);
        } else if (cost < 1000) {
            result = 100 * 0.01 + (500 - 100) * 0.007 + (cost - 500) * 0.0055;
            resultStr = String.format("100 * 0.01 + (500 - 100) * 0.007 + (%f - 500) * 0.0055 = %f", cost, result);
        } else if (cost < 5000) {
            result = 100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (cost - 1000) * 0.0035;
            resultStr = String.format("100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (%f - 1000) * 0.0035 = %f", cost, result);
        } else if (cost < 10000) {
            result = 100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035
                    + (cost - 5000) * 0.002;
            resultStr = String.format("100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035" +
                    " + (%f - 5000) * 0.002 = %f", cost, result);
        } else if (cost < 50000) {
            result = 100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035
                    + (10000 - 5000) * 0.002 + (cost - 10000) * 0.0005;
            resultStr = String.format("100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035" +
                    " + (10000 - 5000) * 0.002 + (%f - 10000) * 0.0005 = %f", cost, result);
        } else if (cost < 100000) {
            result = 100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035
                    + (10000 - 5000) * 0.002 + (50000 - 10000) * 0.0005 + (cost - 50000) * 0.00035;
            resultStr = String.format("100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035" +
                    " + (10000 - 5000) * 0.002 + (50000 - 10000) * 0.0005 + (%f - 50000) * 0.00035 = %f", cost, result);
        } else if (cost < 500000) {
            result = 100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035
                    + (10000 - 5000) * 0.002 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035
                    + (cost - 100000) * 0.00008;
            resultStr = String.format("100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035" +
                    " + (10000 - 5000) * 0.002 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035" +
                    " + (%f - 100000) * 0.00008 = %f", cost, result);
        } else if (cost < 1000000) {
            result = 100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035
                    + (10000 - 5000) * 0.002 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035
                    + (500000 - 100000) * 0.00008 + (cost - 500000) * 0.00006;
            resultStr = String.format("100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035" +
                    " + (10000 - 5000) * 0.002 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035" +
                    " + (500000 - 100000) * 0.00008 + (%f - 500000) * 0.00006 = %f", cost, result);
        } else {
            result = 100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035
                    + (10000 - 5000) * 0.002 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035
                    + (500000 - 100000) * 0.00008 + (1000000 - 500000) * 0.00006 + (cost - 1000000) * 0.00004;
            resultStr = String.format("100 * 0.01 + (500 - 100) * 0.007 + (1000 - 500) * 0.0055 + (5000 - 1000) * 0.0035" +
                    " + (10000 - 5000) * 0.002 + (50000 - 10000) * 0.0005 + (100000 - 50000) * 0.00035" +
                    " + (500000 - 100000) * 0.00008 + (1000000 - 500000) * 0.00006 + (%f - 1000000) * 0.00004 = %f", cost, result);
        }

        return getResultCommon(result, discount, resultStr, height);
    }

    public Result getResultCommon(double result, double discount, String resultStr, int height) {
        // 根据打着折扣计算最终结果
        double afterDis = result * discount;

        Result calResult = new Result();
        calResult.setBeforeDis(0.0D);
        calResult.setAfterDis(0.0D);
        calResult.setBeforeDis(result);
        calResult.setAfterDis(afterDis);
        calResult.setProcedure(resultStr);
        calResult.setHeight(height);

        return calResult;
    }
}
